class VegasVideoMaker
   require 'rexml/document'
   @project = nil
   @medias = []
   @video_event_count = 0
   @audio_event_count = 0

  def self.create
    vvm = self.new()
    doc = REXML::Document.new("<?xml version=\"1.0\"?><Vegas/>")
    vegas = doc.root
    project = vegas.add_element "Project"
    main_video = project.add_element "Video"
    main_video.add_element("Width").add_text "512"
    main_video.add_element("Height").add_text "384"
    main_video.add_element("FrameRate").add_text "30"
    main_video.add_element("FieldOrder").add_text "ProgressiveScan"
    main_video.add_element("PixelAspectRatio").add_text "1"
    main_video.add_element("RenderQuality").add_text "Best"
    main_video.add_element("MotionBlurType").add_text "Gaussian"
    main_video.add_element("DeinterlaceMethod").add_text "None"
    main_audio = project.add_element "Audio"
    main_audio.add_element("SampleRate").add_text "44110"
    main_audio.add_element("BitDepth").add_text "16"
    main_audio.add_element("MasterBusMode").add_text "Stereo"
    main_audio.add_element("ResampleQuality").add_text "Good"
    main_audio.add_element("LFELowpassFilterEnabled").add_text "True"
    main_audio.add_element("LFELowpassFilterCutoffFrequency").add_text "120"
    main_audio.add_element("LFELowpassFilterQuality").add_text "Good"
    project.add_element "MediaPool"
    project.add_element "Tracks"
    vvm.project = project
    return doc, vvm
  end

  def project= new_project
     @project = new_project
     @medias = [] unless @medias
     @video_event_count = 0  unless @video_event_count
     @audio_event_count = 0 unless @audio_event_count
   end
  
  def add_track count = 1, type = 'VideoTrack'
    tracks = @project.get_elements("Tracks").first.elements.to_a("//#{type}")
    (0...count).each do |i|
      new_track = @project.get_elements("Tracks").first.add_element(type)
      index = new_track.add_element("Index")
      index.text = tracks.size + i
      display_index = new_track.add_element("DisplayIndex")
      display_index.text = tracks.size + 1 + i
      media_type = new_track.add_element("MediaType")
      media_type.text = (type == 'VideoTrack' ? 'Video' : 'Audio')
      new_track.add_element("Events")
    end
  end
  
  #options
  #:index
  #:file
  #:pa
  #:fade_in_length, :fade_in_curve, :contain_fade=false
  #:offset, :al
  #:x, :y, :center_x, :center_y
  #:width, :height
  #start_time => VVMTime
  #time_length => VVMTime
  def add_video start_time, time_length, options
    options[:index] ||= 0
    options[:x] ||= 0
    options[:y] ||= 0
    options[:width] ||= 512
    options[:height] ||= 256
    options[:center_x] ||= (options[:width] / 2).to_s
    options[:center_y] ||= (options[:height] / 2).to_s
    options[:fade_in_curve] = 'Smooth' unless options[:fade_in_curve]
    options[:fade_out_curve] = 'Smooth' unless options[:fade_out_curve]
    options[:fade_in_length] = VegasVideoTime.new unless options[:fade_in_length]
    options[:fade_out_length] = VegasVideoTime.new unless options[:fade_out_length]
    time_length = VegasVideoTime.ns(time_length) unless time_length.class == VegasVideoTime
    event = @project.get_elements("Tracks")[0].get_elements("VideoTrack").detect{|vt| vt.get_elements("Index")[0].text == options[:index].to_s}.get_elements("Events")[0]
    #events = event.elements.to_a("//VideoEvent")
    new_event = event.add_element("VideoEvent")
    index = new_event.add_element("Index")
    index.text = @video_event_count
    @video_event_count += 1
    new_event.add_element("MediaType").add_text 'Video'
    new_event.add_element("Start").add_text start_time.to_s
    new_event.add_element("Length").add_text time_length.to_s
    if options[:fade_out_length].nil? || options[:contain_fade] == 'true'
      start_time.add time_length
    elsif options[:contain_fade] != 'none'
      start_time.add(time_length - options[:fade_out_length])
    end
    add_track_pro new_event
    add_take new_event, options[:file], options[:pa], options[:offset]
    add_fade new_event, options
    #VideoMotion
    video_motion = new_event.add_element("VideoMotion")
    video_motion.add_element("ScaleToFill").add_text 'True'
    key_frame = video_motion.add_element("Keyframes").add_element("VideoMotionKeyframe")
    key_frame.add_element("Type").add_text("Linear")
    key_frame.add_element("Position").add_text VegasVideoTime.zero
    key_frame.add_element("Center", {'X' => options[:center_x], 'Y' => options[:center_y]})
    bounds = key_frame.add_element("Bounds")
    bounds.add_element "TopLeft", {'X' => options[:x].to_s, 'Y' => options[:y].to_s}
    bounds.add_element "TopRight", {'X' => (options[:width] + options[:x]).to_s, 'Y' => options[:y].to_s}
    bounds.add_element "BottomRight", {'X' => (options[:width] + options[:x]).to_s, 'Y' => (options[:height] + options[:y]).to_s}
    bounds.add_element "BottomLeft", {'X' => options[:x].to_s, 'Y' => (options[:height] + options[:y]).to_s}
    #END
    add_media options[:file], options[:pa]
  end
  
  def add_audio start_time, time_length, options
    options[:index] = 0 unless options[:index]
    options[:fade_in_curve] = 'Smooth' unless options[:fade_in_curve]
    options[:fade_out_curve] = 'Smooth' unless options[:fade_out_curve]
    options[:fade_in_length] = VegasVideoTime.new unless options[:fade_in_length]
    options[:fade_out_length] = VegasVideoTime.new unless options[:fade_out_length]
    time_length = VegasVideoTime.ns(time_length) unless time_length.class == VegasVideoTime
    event = @project.get_elements("Tracks")[0].get_elements("AudioTrack").detect{|vt| vt.get_elements("Index")[0].text == options[:index].to_s}.get_elements("Events")[0]
    #events = event.elements.to_a("//AudioEvent")
    new_event = event.add_element("AudioEvent")
    index = new_event.add_element("Index")
    index.text = @audio_event_count
    @audio_event_count += 1
    new_event.add_element("MediaType").add_text 'Audio'
    new_event.add_element("Start").add_text start_time.to_s
    new_event.add_element("Length").add_text time_length.to_s
    if options[:time_go]
      start_time.add time_length
    end
    add_track_pro new_event
    add_take new_event, options[:file], options[:pa], options[:offset]
    add_fade new_event, options
    add_media options[:file], options[:pa]
  end
  
  def add_media file, pa
#    medias = @project.get_elements("MediaPool")[0].elements.to_a("Media")
    key_str = pa + file
    unless @medias.include?(key_str)
      media = @project.get_elements("MediaPool")[0].add_element "Media"
      media.add_element("FilePath").add_text key_str
      media.add_element("KeyString").add_text key_str
      @medias << key_str
    end
  end
  
  def add_track_pro new_event
    play_back_rate = new_event.add_element("PlaybackRate")
    play_back_rate.text = 1
    new_event.add_element("Mute").add_text 'False'
    new_event.add_element("Locked").add_text 'True'
    new_event.add_element("Loop").add_text 'True'
    new_event.add_element("Selected").add_text 'False'
    new_event.add_element("UnderSampleRate").add_text '1'
    new_event.add_element("MaintainAspectRatio").add_text 'True'
    new_event.add_element("ReduceInterlace").add_text 'False'
    new_event.add_element("ResampleMode").add_text 'Smart'
  end
  
  def add_take new_event, file, pa, offset=nil
    takes = new_event.add_element("Takes")
    take = takes.add_element("Take")
    take.add_element("Name").add_text file
    take.add_element("Index").add_text '0'
    take.add_element("MediaRef").add_text pa+file
    take.add_element("MediaPath").add_text pa+file
    take.add_element("StreamIndex").add_text '0'
    take.add_element("IsActive").add_text 'True'
    take.add_element("Offset").add_text offset.to_s if offset
  end
  
  def add_fade new_event, options
    fade_in = new_event.add_element("FadeIn")
    fade_in.add_element("Length").add_text(options[:fade_in_length].to_s)
    fade_in.add_element("Curve").add_text(options[:fade_in_curve])
    fade_in.add_element("Gain").add_text '1'
    if options[:fade_in_type]
      transition = fade_in.add_element("Transition")
      transition.add_element("PlugIn").add_text options[:fade_in_type]
    end
    fade_out = new_event.add_element("FadeOut")
    fade_out.add_element("Length").add_text(options[:fade_out_length].to_s)
    fade_out.add_element("Curve").add_text(options[:fade_out_curve])
    fade_out.add_element("Gain").add_text '1'
    fade_out.add_element("Gain").add_text '1'
    if options[:fade_out_type]
      transition = fade_out.add_element("Transition")
      transition.add_element("PlugIn").add_text options[:fade_out_type]
    end
  end
  
  def add_video_and_audio start_time, time_length, options
    add_audio start_time, time_length, options.merge(:index => nil)
    if options[:pic_fade] == 'all'
      add_video start_time, time_length, options
    elsif options[:pic_fade]
      add_video start_time, time_length, options.merge(:fade_in_length => nil)
    else
      add_video start_time, time_length, options.merge(:fade_in_length => nil, :fade_out_length => nil)
    end
  end
end